<template>
  <el-dialog
    v-model="dialogShow"
    title="过滤器函数编辑器"
    width="80%"
    @open="open"
    @close="close"
    top="10px"
    :z-index="99"
    :close-on-click-modal="false"
  >
    <div class="cont">
      <div class="body">
        <div class="left">
          <div class="fn-head">
            <span class="func-keyword">function</span>&nbsp;&nbsp;filter(data,
            res)&nbsp;&nbsp;{
          </div>
          <!-- <div v-if="dialogShow"> -->
          <monaco-editor
            v-model:modelValue="filter"
            width="100%"
            height="480px"
            language="javascript"
          />
          <!-- </div> -->

          <div class="fn-foot">}</div>
        </div>
        <div class="right">
          <div class="card">
            <div class="name">
              默认过滤数据(data)：<span
                class="no-data"
                v-if="isEmpty(filterString.data)"
                >暂无</span
              >
            </div>
            <div class="value" v-if="!isEmpty(filterString.data)">
              <el-input
                v-model="filterString.data"
                readonly
                resize="none"
                type="textarea"
                class="inp-code"
              />
            </div>
          </div>
          <div class="card">
            <div class="name">
              接口返回数据(res)：<span
                class="no-data"
                v-if="isEmpty(filterString.res)"
                >暂无</span
              >
            </div>
            <div class="value" v-if="!isEmpty(filterString.res)">
              <el-input
                v-model="filterString.res"
                readonly
                resize="none"
                type="textarea"
                class="inp-code"
              />
            </div>
          </div>
          <div class="card">
            <div class="name">
              过滤器返回结果：<span
                class="no-data"
                v-if="isEmpty(filterString.filterRes)"
                >暂无</span
              >
            </div>
            <div class="value" v-if="!isEmpty(filterString.filterRes)">
              <el-input
                v-model="filterString.filterRes"
                readonly
                resize="none"
                type="textarea"
                class="inp-code"
              />
            </div>
          </div>
        </div>
      </div>
      <div class="footer">
        <div class="rile">规则:过滤器默认处理接口返回值的「data」字段</div>
        <div class="btns">
          <el-button class="btn" type="primary" @click="close">取 消</el-button>
          <el-button class="btn" type="primary" @click="save">确 认</el-button>
        </div>
      </div>
    </div>
  </el-dialog>
</template>
<script setup>
import { computed, reactive, ref, toRaw, defineAsyncComponent } from "vue";
// import monacoEditor from "@/components/MonacoEditor/index.vue"
import { customizeHttp } from "@/api/http";
import { useStore } from "vuex";
import { ElMessage } from "element-plus";
import { formartJsonStr } from "@/utils/index.js";

const monacoEditor = defineAsyncComponent(() =>
  import("@/components/MonacoEditor/index.vue")
);
let store = useStore();
let props = defineProps({
  filterShow: {
    type: Boolean,
    default: false,
  },
});
let emit = defineEmits(["update:filterShow"]);

let filter = ref("");
let sourceData = ref();
let errorFlag = ref(false);

let filterString = computed(() => {
  let data = formartJsonStr(JSON.stringify(sourceData.value?.data ?? ""));
  let res = formartJsonStr(JSON.stringify(sourceData.value ?? ""));
  let filterRes = "";
  try {
    const fn = new Function("data", "res", filter.value);
    const response = JSON.parse(JSON.stringify(sourceData.value ?? {}));
    const result = fn(response?.data, response);
    errorFlag.value = false;
    filterRes = formartJsonStr(JSON.stringify(result ?? ""));
  } catch (error) {
    errorFlag.value = true;
    filterRes = `过滤函数错误，日志：${error}`;
  }
  return {
    data: data,
    res: res,
    filterRes: filterRes,
  };
});

let dialogShow = computed(() => {
  return props.filterShow;
});
let selectedComponent = computed(() => {
  return store.state.chartEditStore.selectedComponent;
});
let requestGlobalConfig = computed(() => {
  return store.state.chartEditStore.requestGlobalConfig;
});

// 动态获取数据
const fetchTargetData = async () => {
  try {
    const res = await customizeHttp(
      toRaw(selectedComponent.value.request),
      toRaw(requestGlobalConfig.value)
    );
    if (res) {
      sourceData.value = res;
      return;
    }
    ElMessage.warning("没有拿到返回值，请检查接口！");
  } catch (error) {
    console.error(error);
    ElMessage.warning("数据异常，请检查参数！");
  }
};

function open() {
  fetchTargetData();
  filter.value =
    store.state.chartEditStore?.selectedComponent?.filter ?? "return data";
}

function close() {
  filter.value = "";
  emit("update:filterShow", false);
}

function save() {
  if (errorFlag.value) {
    ElMessage.error("过滤函数错误，无法进行保存");
    return;
  }
  selectedComponent.value.filter = filter.value;
  close();
}

function isEmpty(val) {
  return val == '""' || val == undefined || val == null;
}
</script>
<style lang="scss" scoped>
.cont {
  .body {
    height: 540px;
    display: flex;
    .left {
      width: 60%;
      padding: 10px;
      border-right: 1px solid #777;
      .fn-head,
      .fn-foot {
        color: #70c0e8;
        height: 20px;
      }
      .func-keyword {
        color: #b478cf;
      }
    }
    .right {
      flex: 1;
      padding-top: 10px;
      padding-left: 20px;
      .card {
        border-radius: 5px;
        background-color: #f0f0f0b3;
        margin-bottom: 20px;
        padding: 10px;
        // padding-top: 0;
        .name {
          height: 30px;
          line-height: 30px;
        }
        .value {
          // max-height: 120px;
          overflow: auto;

          .inp-code {
            min-height: 0;
            width: 100%;
            :deep(.el-textarea__inner) {
              height: 110px;
              color: #555 !important;
            }
          }
        }
      }
    }
  }
  .footer {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0 10px;
    height: 40px;
  }
}
</style>
